VERSION = 3.00 j%3IEUUGotFocus,13!) graphpreview autgraph.hU* autograph autgraph.hntotaldataflds icurrrec PixelsClass1 automation autographcustom commandbutton+PROCEDURE Click THISFORM.HIDE() ENDPROC pTop = 265 Left = 156 Height = 39 Width = 127 Caption = "Return To Wizard" TabIndex = 1 Name = "command1"  commandbutton!Arial, 0, 9, 5, 15, 12, 13, 3, 0  cmdreturnPixelsClass commandbutton cmdreturn31jTop = 0 Left = 0 Height = 250 Width = 450 Sizable = .F. AutoActivate = 2 Name = "oleboundcontrol1"  commandbutton graphpreviewformcommand1!Arial, 0, 9, 5, 15, 12, 13, 3, 0  graphpreviewPixelsClassform graphpreviewHeight = 315 Width = 450 DoCreate = .T. AutoCenter = .T. Caption = "Graph Preview" Closable = .F. WindowType = 1 AlwaysOnTop = .T. DefOleLCID = 0 Name = "graphpreview" ,PROCEDURE GotFocus * nodefault ENDPROC oleboundcontrol1oleboundcontrololeboundcontrol[Height = 39 Width = 127 Caption = "Return To Wizard" Default = .T. Name = "cmdreturn" +PROCEDURE Click THISFORM.Hide() ENDPROC naction Output action (0-preview, 1-save to form, 2- save to table, 3- save to query). coutfile Name of outfile if any. ccategoryfield ncharttype Numeric code for chart type nchartsubtype Sub type of chart. luseautoformat Use MS Graph autocharting gallery. ngraphversion Version of Graph being used. ctitle Title caption of chart. laddtitle Add title to chart. laddeddata Flag if data already added for performance. lshownulls Display nulls in chart. lseriesbyrow Plot series by row or column. cgraphfldrow cgraphfldcol cgraphfield clastdatarow clastdatacol ographref graphpreview lautograph laddlegend Add legend to chart. lhadpreview copenalias coutgenfield cdefnewfield cgraphdbf cgraphprevclass coleserver lreplacedbf nchartautoformat Gallery chart format for autoformat (setting 2). nchartautogallery Gallery chart format for autoformat (setting 1). ntotaldataflds ndataseries ndatacount lstripexcesslegend nlastaction ldontstriplegend lshowwhendone If .T., do SHOW of preview form when done luse8type Use the charttype property for setting chart type. lgraphrecord Whether to graph current record or entire cursor. icurrrec Hold the current record number, if only graphing one record. lkeepform Use user supplied form and olecontrol? *msgraphcheck *getsavefile *checktable *makeqpr ^adatafields[1,1] Array of data fields. *addgraphdata Adds data to chart. *validdatatable *getoledata *setcapitals *maptochar *addgraphfx Adds chart formatting. *getoleserver `naction = 1 coutfile = ccategoryfield = ncharttype = 1 nchartsubtype = 1 ngraphversion = 5 ctitle = laddtitle = .T. lshownulls = .T. lseriesbyrow = .T. cgraphfldrow = cgraphfldcol = cgraphfield = clastdatarow = clastdatacol = laddlegend = .T. copenalias = coutgenfield = cdefnewfield = cgraphdbf = cgraphprevclass = coleserver = lreplacedbf = .T. nchartautoformat = 1 nchartautogallery = 1 ndataseries = 0 ndatacount = 0 nlastaction = 99 lshowwhendone = .T. nsavelocaleid = 1033 builder = builderx = (HOME()+"Wizards\BuilderD,BuilderDForm") Name = "autograph"  automate.vcxQ PPr%HO?AIUTCFileRegNT MSGraph.Chart T T TC a% %CyMicrosoft Graph does not appear to be installed properly. The latest version of Graph is available from Microsoft Office.xB-%C 0  T TTC % CyMicrosoft Graph does not appear to be installed properly. The latest version of Graph is available from Microsoft Office.xB-%C 0 VCJCould not locate MS Graph file. Please reinstall it from Microsoft Office.xB-TCC Rg% .lC`You must have MS Graph version 8.0 loaded. Please install correct version from Microsoft Office.xB-(?%C MSGraph.Chart.CC Z   C T !BaU CAPPKEYCAPPNAMENERRNUMCCLASSIOREGGETLATESTVERSIONTHIS NGRAPHVERSIONOPENKEYCLOSEKEY H'y BBa 0TSCXITCCCCDATABASE ꉡ C SourceName 6  TSave graph in form:TCSAFETYvG.TC   SET SAFETY &cOldSafe BC  Q BC y Hr%1  C sourcetype  TCC &QPR   TC =.QPR2%,TCC sourcename QPR TQPR!TSave graph in query:BC    U CCURALIASCEXTCPROMPT CSAVEFILECOLDSAFETHISNACTIONCOUTFILE CHECKTABLE NCURRENTOSFORCEEXT SAVEOUTFILETDBFT vfpgraph.dbf!TSave graph in table: TCWTCSAFETYv T +aiT  T%C T %C G.TC   SET SAFETY &cOldSafe %C K!TC DBF %C 0 !T %C 0 !TC  &%C CC &fC f  F  T%C FT aQ T -%CC9C)The table you selected is already in use..(C.%CC /bGT C /!%C "Ta8T-%%C  C i!T aQ T -%CC9C)The table you selected is already in use.. %CsH4C$The table you selected is read-only.%C @Q.%C aQ!T  T  F BC  UI NSAVEAREACTMPFILECEXTCPROMPT CSAVEFILE COPENALIASCOLDSAFETHIS COUTGENFIELDCOUTFILEFORCEEXTJUSTSTEM SETERROROFFALERT LREPLACEDBF'T CWT C]%CCdatabaseꉡ ~TCC SourceNameꉼTCC& ] TC%C T  . (C O%CC  .0T  ,  .C  %CCdatabaseꉡ +TCCCdatabase ] T !  T' '  %  T  T  7T  T  h MN>SELECT ;C C  FROM  ;C C  INTO CURSOR SYS(2015)C C DO (_GENGRAPH) WITH  'AUTOGRAPH',CC Z,CC Z,' ',C  .T..F.6,C  .T..F.6,C  .T..F.6,,.F.C  ,.T.6( Q F U CTMPCURSORNWKAREA CSQLALIASFLDEXPRCTMPTYPECTMPSUBCDBCPATHI CSQLSOURCETHISCOUTFILECCATEGORYFIELD ADATAFIELDSJUSTSTEMLUSEAUTOFORMATNCHARTAUTOGALLERYNCHARTAUTOFORMAT NCHARTTYPE NCHARTSUBTYPE SQLSTRINGCTITLE LSERIESBYROW LADDLEGEND LSHOWNULLS# %C 9B-TC!%Cvfpgtemp }F % #%     T C %C T-B-T _C]FQ   H4 ( CbGCbG GC;The source graph table does not have a valid General field.xB-( CbGCbG ! CbG T-   TaC%CvfpgtempQQ hvfpgtempF   Q TT%T% B&T% "B"R,:Adding data to graph... R %~B-%T T Ta%C B-5 5T "R,:Adding data to graph..." 00:Z99!T C %C T-B- TT  00"#T T BaU$ CDATACONTENTS AGRAPHFLDSCTMPCURS COLDCLIPTEXTTHIS CHECKDATANTOTALDATAFLDS ADATAFIELDS LADDEDDATAVFPGTEMPNACTION NGRAPHVERSION GETOLEDATA CGRAPHDBF CGRAPHFLDROW CGRAPHFLDCOL LSERIESBYROW CLASTDATAROW CLASTDATACOL CGRAPHFIELDHADERROR GETOLESERVERIFLDCOLS FIELDNAME NNULLCOUNT NFIELDVALUE CLINEDATA OGRAPHREF APPLICATION DATASHEETRANGEDELETEPASTEUPDATE  ( H7 u$CNo data points to graph.xB- pCYou have over CCZ records in your table. -This exceeds the maximum allowed by MS Graph.xB- dCYou have over CCdZ records to graph. +The graph may be crowded and hard to read. (Do you want to prepare the graph anyway?$x B-&%CC C T$%C CC  C.(C.aT C /L%C 6CTHIS.cCategoryFieldbCCCf  FC:The category field specified is not in the selected table.xB-%C (CG%CTHIS.aDataFields[m.i]bCCCC f @C4One of the data fields is not in the selected table.xB- H C C  TC/ CC (CjT CC f (C.%CC /TC /!%C (C.%C /Cf.&%CCC /bNFYB <.%C lCTCC / (Cs#%CC bNFYB o%C,The data fields chosen are not all numeric. EDo you want to continue plotting only those series which are numeric?$xkB-TC%CT-"%    T BaU NTOTRECSIATMPDATAAFLDDATATHIS ADATAFIELDSCCATEGORYFIELDCTITLE LADDTITLE NGRAPHVERSIONNCHARTAUTOGALLERYg5 5T T  C T  ( *T C  %%C  C bNFYB &3T CC =N_ C \ 6T  C  T  T  C C % -C!No numeric data fields were foundx BT % TNEXT 1 # TALLSCAN &cScope.T CC CC  6 T ( 5%CC  CC  bNFYB TC  TC  H C T C T  C 8 ;T C CC Z CC  bY~%T C CC Z2%T C CC Z!%   .#T   C C T  % U%C CNQ #  B UCSCOPEICOLEDATAFLDCOLS FIELDNAME NNULLCOUNT NFIELDVALUE CLINEDATATHIS SETCAPITALSNTOTALDATAFLDS ADATAFIELDS NDATACOUNT LGRAPHRECORDICURRRECCCATEGORYFIELD MAPTOCHAR LSHOWNULLS%:%CTHIS.nCatCapitalbNC >B(C Hr $T CC @ $T CC f $T CC UTHIS NCATCAPITALI ADATAFIELDSW T Cm.valueb H5P C S BNull C CMw B ! C NFBYBCC Z D BC * TBC  LBC YESNO6 G? BOle2P BUVALUE CDATATYPEjR,:Formatting graph..."%  %C hB-0%CTHIS.oGraphRef.controlsourcebU% T % B-T  % B-T %_T% %CTTR B c%  H @C fT2TTT -T %T% B-%YT T!"tT!#% B-T $%T&a% !<$( !8$ '% 4T&-B-T&-%T T!#T "(%()CA" '%* T!"%)T $%% !$( !G%C3THIS.oGraphRef.SeriesCollection(m.iSeriesCount - i)bO$ 'T $%( D%C0THIS.oGraphRef.SeriesCollection(i).HasDataLabelsbLT$+-% = H9 C T29TTT  % M,I%ET -%%. A% !=$( !96%C".LegendEntries(m.iLegendCount - i)bO5- 'R B U/ ISERIESCOUNT ILEGENDCOUNTITHISNACTION NGRAPHVERSION GETOLESERVER OGRAPHREF CONTROLSOURCE CGRAPHFIELDHADERROR HASLEGEND LADDLEGENDHASTITLE LADDTITLE CHARTTITLECAPTIONCTITLE LHADPREVIEWLUSEAUTOFORMAT AUTOFORMATNCHARTAUTOGALLERYNCHARTAUTOFORMATTYPE NCHARTTYPESUBTYPE NCHARTSUBTYPE LUSE8TYPE CHARTTYPETEXT LSERIESBYROW APPLICATIONPLOTBY NDATASERIESNTOTALDATAFLDS NDATACOUNTSERIESCOLLECTIONCOUNT SETERROROFFDELETE DATASHEETRANGELSTRIPEXCESSLEGEND HASDATALABELSLEGEND LEGENDENTRIESLDONTSTRIPLEGENDa Ta Ta2%CTHIS.GraphPreviewbO C %CC @form T-T -/%CTHIS.oGraphRefbO C yT % u"% Microsoft GraphqTC g% m% i T-T - H}) CCDBF TCNT  T - % CTCformNT% 8CoChart oleControlMSGraph.Chart.8TaT  TT, T al   FCTHIS.graphpreviewbOCTHIS.oGraphRefbO  C  TCNT  T -N CTHIS.graphpreviewbOCTHIS.oGraphRefbO  C }% TCformN% 8CoChart oleControlMSGraph.Chart.8T  TT T a% yuT;TT Graph Preview Ta Ta T-T )C cmdReturn cmdReturn"!T#aT#$T#% ,%CTHIS.oGraphRefbO B-E% #CTHIS.graphpreview.oChartbO C ZVT T  T&aT' TaU(IHEIGHTIWIDTHLSETPREVIEWPROPS LCREATEFORMLADDGRAPHOBJECTCAPPNAME CAPPVERSIONTHIS GRAPHPREVIEW BASECLASSHADERROR OGRAPHREF APPLICATIONNAMEVERSION LAUTOGRAPHCOUTFILECGRAPHPREVCLASSOLEBOUNDCONTROL1 DEFOLELCID ADDOBJECTOCHARTVISIBLEOBJECTNACTION NGRAPHVERSIONHEIGHTWIDTHCAPTION ALWAYSONTOP AUTOCENTERCLOSABLE WINDOWTYPE NEWOBJECT CLASSLIBRARY CMDRETURNLEFTTOPAUTOSIZESTRETCH>TCC ]g%C *B- BCUTHIS NSAVELOCALEID MSGRAPHCHECKT- H. CCC EC9No datasource selected. Graph automation tool terminated.xB- CTC2 F %C  TCC %CB)% CCDBF PT% %CCOCNT COB%(%C B- CT '',_SHELL = [MODIFY QUERY &cQPRFile NOWAIT] BC  ]"% TTTT-%C B-%C B- H >/%CTHIS.graphpreviewbO :  ]T CSAFETYvG.P:%CTHIS.graphpreview.cmdReturnbOC C cmdReturnT T- TaETCCCDATABASEꉡ C SourceName6CSET SAFETY &cOldSafe %C?An error occurred in writing your graph to the selected table. ,Check to see if the table is already in use.B-.%CCtGRSTARTWIZARD Y%T7 MODIFY FORM "" TTT CSAFETYvG.T T-T a)%C0 ! C" Xh1#G5INSERT INTO (DBF()) VALUE(vfpgtemp.&cGraphField.) %C$FQ F$KINSERT INTO (DBF()) ((THIS.cOutGenField)) VALUE(vfpgtemp.&cGraphField.) T#"T -SET SAFETY &cOldSafe %C?An error occurred in writing your graph to the selected table. ,Check to see if the table is already in use.B-T C.#.%CCtGRSTARTWIZARD  Hm CoEnginebOCCC%& CoWizardbOmCC'&-_SHELL = [MODIFY GENERAL &cTmpFld NOWAIT] U(CTMPFLDCQPRFILECOLDSAFE CGRAPHFIELDTHISHADERRORCALIASCOUTFILENACTION GETSAVEFILE LAUTOGRAPH LGRAPHRECORDICURRREC CHECKDATAMAKEQPR NLASTACTION LKEEPFORM OGRAPHREF GRAPHPREVIEW LADDEDDATA ADDGRAPHDATA ADDGRAPHFX LSHOWWHENDONESHOW CMDRETURN REMOVEOBJECT WINDOWTYPE ALWAYSONTOPCLOSABLECAPTIONSAVEASALERT SETERROROFF LREPLACEDBF COUTGENFIELD CDEFNEWFIELD COPENALIASOENGINEADDALIASTOPRESERVEDLISTOWIZARDOTT%Cvfpgtemp?Q CUTHIS OGRAPHREF GRAPHPREVIEWVFPGTEMP2 %<TaB T Cz(% CC ^C0Could not proceed because an OLE Error Occurred. (Error: CCCZ)TaBC  ] C   U NERRORCMETHODNLINE NTOTERRORSAERRSTHIS SETERROROFFHADERRORALERT NSAVELOCALEID AUTOMATIONERROR~ T CEXACTvG T CSET EXACT &cOldExact % wT-B-ULRETVAL COLDEXACTTHISVALIDDATATABLE LADDEDDATA msgraphcheck, getsavefile[ checktableVmakeqpr addgraphdatavaliddatatable; getoledata setcapitals$ maptochar)& addgraphfx' getoleserver52InitL: makeoutput:Destroy-EErrorE checkdataPG1u1QqA#1QqA"aqAAAqA!AAAq3q1AqBQaBBAAA3qQA"aAA!AA!AAAsaAAAAcAAAA$ABAAAAAAAAAAAAA!!3s!A3AAAAA!!!!AbQ!A31"qAqA22qAbrqqArARq1aAA1aAAA"cRqA!!A#qAs"#2qABBBr331AqAq qAcACaAaqA1qqAAAA"!AAAAAAA#AAaAA2AAA1qAAAS!A"Ar3tQ3QAA2A1AAQq1qQQAAAAA1qBrAA3AAqAAAAAAAA3q!AAAAA3""qAaqAAAcqAcAaaAARaaaAAc1AAqAa12AqAaAqAAAa1aRA1bAqAAAAAAAAAaaaAAc11aAaqAAAAAAARB21#AAa!1AAAAAaaq1AAAbaqAA!AAAqAR1AA2QqA21Qq!A!AAAA1BAAB!qAAA"1A"qA"qAAABqaqAQAqAQABsa!Q!A1AqAABB3qA3AAAAA"3ba1qA2H&j 8D h]Lo%%i0f0::\:$<XD<d>j>QOR\8]~]]@k^kk@%kmI5mn^)P %Pe_U CUTHISFORMHIDEClick,11 ) %Pe_U CUTHISFORMHIDEClick,11 )nPROCEDURE msgraphcheck LOCAL cAppKey,cAppName,nErrNum,cClass,i, oReg *- REGISTRY.VCX is added to the CLASSLIB list in the INIT of the *- AUTOMATION class oReg = create('FileReg') cClass = MSGRAPH_CLASS cAppKey = "" cAppName = "" * Get MS Graph Registry entry nErrNum = oReg.GetLatestVersion(m.cClass,@cAppKey,@cAppName,.T.) IF m.nErrNum # ERROR_SUCCESS =MESSAGEBOX(C_BADMSGRAPH_LOC) RETURN .F. ENDIF * Does file exist? IF !FILE(m.cAppName) * If fail, try different Registy key cAppName = "" cAppKey = "" nErrNum = oReg.GetLatestVersion(m.cClass,@cAppKey,@cAppName) IF m.nErrNum # ERROR_SUCCESS =MESSAGEBOX(C_BADMSGRAPH_LOC) RETURN .F. ENDIF IF !FILE(m.cAppName) =MESSAGEBOX(C_NOMSGRAPH_LOC) RETURN .F. ENDIF ENDIF * Is this a valid version of MS Graph (>3.0)? THIS.nGraphVersion = VAL(RIGHT(m.cAppKey,1)) IF THIS.nGraphVersion < MSGRAPH_VERSION =MESSAGEBOX(C_MSGRAPHVER_LOC) RETURN .F. ENDIF * Let's check for newer version of Graph which may be higher than * registered current version, but somehow got messed up in Registry. FOR i = THIS.nGraphVersion+1 TO 15 IF oReg.OpenKey(MSGRAPH_CLASS+"."+ALLTRIM(STR(m.i)),HKEY_CLASSES_ROOT) = 0 oReg.CloseKey() THIS.nGraphVersion = m.i EXIT ENDIF ENDFOR RETURN .T. &&OK ENDPROC PROCEDURE getsavefile LPARAMETERS cCurAlias LOCAL cExt,cPrompt,cSaveFile, cOldSafe DO CASE CASE THIS.nAction = 0 RETURN .T. CASE THIS.nAction = 1 && save to form cExt = "SCX" cSaveFile = FORCEEXT(IIF(EMPTY(CURSORGETPROP("DATABASE", m.cCurAlias)), m.cCurAlias, CURSORGETPROP("SourceName", m.cCurAlias)),m.cExt) cPrompt = C_SAVEPROMPT3_LOC cOldSafe = SET('SAFETY') SET SAFETY OFF THIS.cOutFile = PUTFILE(m.cPrompt,m.cSaveFile,m.cExt) SET SAFETY &cOldSafe RETURN (!EMPTY(THIS.cOutFile)) CASE THIS.nAction = 2 && save to table RETURN THIS.CheckTable() CASE THIS.nAction = 3 && save to query DO CASE CASE THIS.nCurrentOS = OS_W32S AND ; CURSORGETPROP("sourcetype",m.cCurAlias) = 3 * use short DOS name for Win32S cSaveFile = THIS.ForceExt(DBF(m.cCurAlias),"QPR") CASE THIS.nCurrentOS = OS_W32S cSaveFile = LEFT(m.cCurAlias,8) + ".QPR" OTHERWISE cSaveFile = THIS.ForceExt(cursorgetprop("sourcename",m.cCurAlias),"QPR") ENDCASE cExt = "QPR" cPrompt = C_SAVEPROMPT2_LOC RETURN THIS.SaveOutFile(m.cPrompt,m.cSaveFile,m.cExt) &&use canceled ENDCASE ENDPROC PROCEDURE checktable LOCAL i,nSaveArea,cTmpFile LOCAL cExt,cPrompt,cSaveFile,cOpenAlias,cOldSafe cExt = "DBF" cSaveFile = C_GRAPHDBF cPrompt = C_SAVEPROMPT1_LOC nSaveArea = SELECT() cOldSafe = SET('SAFETY') cTmpFile = "" DO WHILE .T. THIS.cOutGenField = "" &&reset field cOpenAlias = "" * Check if THIS.cOutFile passed failed IF !EMPTY(cTmpFile) THIS.cOutFile = "" ENDIF IF EMPTY(THIS.cOutFile) SET SAFETY OFF cTmpFile = PUTFILE(m.cPrompt,m.cSaveFile,m.cExt) SET SAFETY &cOldSafe * User hit canceled IF EMPTY(m.cTmpFile) EXIT ENDIF * File does not exist so, lets skip check cTmpFile = THIS.ForceExt(m.cTmpFile,"DBF") IF !FILE(m.cTmpFile) EXIT ENDIF ELSE cTmpFile = THIS.cOutFile IF !FILE(m.cTmpFile) EXIT ENDIF ENDIF * See if we already have file open and use it. cOpenAlias = THIS.JUSTSTEM(m.cTmpFile) IF USED(m.cOpenAlias) AND UPPER(DBF(m.cOpenAlias)) = UPPER(m.cTmpFile) SELECT (m.cOpenAlias) ELSE cOpenAlias = "" ENDIF * Test file for already in-use IF EMPTY(m.cOpenAlias) SELECT 0 THIS.SetErrorOff = .T. USE (m.cTmpFile) AGAIN SHARED THIS.SetErrorOff = .F. * Failed to open file shared -- file in use IF EMPTY(ALIAS()) THIS.ALERT(C_FILEINUSE_LOC) LOOP ENDIF ENDIF * Test for General fields in table FOR i = 1 TO FCOUNT() IF TYPE(FIELD(m.i)) = "G" THIS.cOutGenField = FIELD(m.i) EXIT ENDIF ENDFOR * Table selected has no General field * so let's not allow them to append. IF EMPTY(THIS.cOutGenField) * By default, use replace option here. THIS.lReplaceDBF = .T. ELSE THIS.lReplaceDBF = .F. ENDIF IF THIS.lReplaceDBF * Table already opened IF !EMPTY(m.cOpenAlias) AND ISEXCLUSIVE() * All is well, so let's just exit EXIT ENDIF * Let's test to make sure that we can entire overwrite table THIS.SetErrorOff = .T. USE (m.cTmpFile) AGAIN EXCLUSIVE THIS.SetErrorOff = .F. * Failed to open file exclusive -- file in use IF EMPTY(ALIAS()) THIS.ALERT(C_FILEINUSE_LOC) LOOP ENDIF ENDIF * Test for read-only IF ISREADONLY() THIS.ALERT(C_READONLY_LOC) IF EMPTY(m.cOpenAlias) USE ENDIF LOOP ENDIF IF EMPTY(m.cOpenAlias) USE ENDIF EXIT ENDDO THIS.cOutFile = m.cTmpFile THIS.cOpenAlias = m.cOpenAlias SELECT (m.nSaveArea) RETURN !EMPTY(m.cTmpFile) ENDPROC PROCEDURE makeqpr *- Makes a temporary cursor with memo to create QPR files LOCAL cTmpCursor,nWkArea,cSQLAlias,fldExpr,cTmpType,cTmpSub,cDBCPath,i,; cSQLSource m.nWkArea = SELECT() m.cTmpCursor = SYS(2015) IF !EMPTY(CURSORGETPROP("database")) && DBC stuff cSQLSource= PROPER(CURSORGETPROP("SourceName")) ELSE && table cSQLSource = SYS(2014,DBF(),THIS.cOutFile) ENDIF cSQLAlias = ALIAS() * Get SQL Select statement pieces IF !EMPTY(THIS.cCategoryField) m.fldExpr = m.cSQLAlias + "." + THIS.cCategoryField ENDIF FOR i = 1 TO ALEN(THIS.aDataFields) IF EMPTY(THIS.aDataFields[m.i]) LOOP ENDIF m.fldExpr=m.fldExpr + ", "+m.cSQLAlias + "." + THIS.aDataFields[m.i] ENDFOR IF !EMPTY(CURSORGETPROP('database')) &&lets put the DBC alias before table cDBCPath = THIS.JustStem(SYS(2014,CURSORGETPROP('database'),THIS.cOutFile)) cSQLSource = m.cDBCPath + "!" + m.cSQLSource ENDIF cSQLSource = "'" + m.cSQLSource + "' " + m.cSQLAlias IF THIS.lUseAutoFormat m.cTmpType = THIS.nChartAutoGallery m.cTmpSub = THIS.nChartAutoFormat ELSE m.cTmpType = THIS.nChartType m.cTmpSub = THIS.nChartSubType ENDIF CREATE CURSOR (m.cTmpCursor) (sqlstring m) APPEND BLANK REPLACE sqlstring WITH ; "SELECT "+m.fldExpr + ";" + CRLF +; " FROM " + m.cSQLSource + ";" + CRLF +; " INTO CURSOR SYS(2015)" + CRLF +; "DO (_GENGRAPH) WITH "+; "'AUTOGRAPH',"+; ALLTRIM(STR(m.cTmpType))+","+; ALLTRIM(STR(m.cTmpSub))+","+; "'"+THIS.cTitle+"',"+; IIF(THIS.lSeriesByRow ,".T.",".F.")+","+; IIF(THIS.lAddLegend,".T.",".F.")+","+; IIF(THIS.lUseAutoFormat,".T.",".F.")+; ",,.F." + ; IIF(THIS.lShowNulls,",.T.","") ADDITIVE COPY MEMO sqlstring TO (THIS.cOutFile) USE SELECT (m.nWkArea) ENDPROC PROCEDURE addgraphdata LOCAL cDataContents, aGraphFlds, cTmpCurs, cOldClipText DIMENSION aGraphFlds[1] IF !THIS.CheckData() RETURN .F. ENDIF THIS.ntotaldataflds = ALEN(THIS.aDataFields,1) IF THIS.lAddedData AND USED('vfpgtemp') SELECT vfpgtemp ENDIF IF !THIS.lAddedData IF THIS.nAction = 2 OR (THIS.ngraphVersion < 8) *- save to a table m.cDataContents = THIS.GetOleData() IF EMPTY(m.cDataContents) THIS.lAddedData = .F. RETURN .F. ENDIF m.cTmpCurs = "_"+SYS(3) SELECT 0 * Open DBF containing General field with source MS Graph USE (THIS.cGraphDBF) AGAIN ALIAS(m.cTmpCurs) * Check to make sure we have valid Graph DBF DO CASE CASE TYPE(THIS.cGraphFldRow)#"G" AND TYPE(THIS.cGraphFldCol)#"G" =MESSAGEBOX(C_BADFIELDS_LOC) RETURN .F. CASE TYPE(THIS.cGraphFldRow)="G" AND TYPE(THIS.cGraphFldCol)="G" * do nothing CASE TYPE(THIS.cGraphFldRow)#"G" AND THIS.lSeriesByRow THIS.lSeriesByRow = .F. CASE !THIS.lSeriesByRow && cGraphFldCol # "G" THIS.lSeriesByRow = .T. ENDCASE =AFIELDS(aGraphFlds) IF USED('vfpgtemp') USE IN vfpgtemp ENDIF CREATE CURSOR vfpgtemp FROM ARRAY aGraphFlds SELECT vfpgtemp APPEND FROM (THIS.cGraphDBF) USE IN (m.cTmpCurs) THIS.cLastDataRow = "" && reset THIS.cLastDataCol = "" && reset * Select graph based on Series By Row/Col IF THIS.lSeriesByRow THIS.cGraphField = THIS.cGraphFldRow IF THIS.cLastDataRow = m.cDataContents RETURN ENDIF ELSE THIS.cGraphField = THIS.cGraphFldCol IF THIS.cLastDataCol = m.cDataContents RETURN ENDIF ENDIF WAIT WINDOW NOWAIT C_WAITDATA_LOC *- Add data to General field APPEND GENERAL (THIS.cGraphField) DATA m.cDataContents WAIT CLEAR IF THIS.Haderror RETURN .F. ENDIF *- Set so we don't have to read data later IF THIS.lSeriesByRow THIS.cLastDataRow = m.cDataContents ELSE THIS.cLastDataCol = m.cDataContents ENDIF THIS.lAddedData = .T. ELSE *- save to a form IF !THIS.GetOleServer() RETURN .F. ENDIF *- Set value of cells in graph's DataSheet PRIVATE i,fld,cols,fieldname,nNullCount PRIVATE nfieldvalue,cLinedata m.cLineData = "" WAIT WINDOW NOWAIT C_WAITDATA_LOC *- delete contents THIS.oGraphRef.application.datasheet.range("00:Z99").delete m.cDataContents = THIS.GetOleData() IF EMPTY(m.cDataContents) THIS.lAddedData = .F. RETURN .F. ENDIF cOldClipText = _cliptext _cliptext = m.cDataContents THIS.oGraphRef.Application.Datasheet.Range("00").Paste THIS.oGraphRef.Application.Update *- restore _cliptext _cliptext = m.cOldClipText THIS.lAddedData = !THIS.HadError ENDIF && THIS.nAction = 2 (output to table) ENDIF && THIS.lAddedData RETURN .t. ENDPROC PROCEDURE validdatatable * Note: if no aDataFields or cCategoryField, try to find some LOCAL nTotRecs,i,aTmpData,aFldData DIMENSION aTmpData[1] * Check for too many records in datasource COUNT TO m.nTotRecs DO CASE CASE m.nTotRecs = 0 =MESSAGEBOX(C_NODATAPOINTS_LOC) RETURN .F. CASE m.nTotRecs > MAX_MSGRAPH =MESSAGEBOX(C_MAXGRAPH_LOC) RETURN .F. CASE m.nTotRecs > MAX_DATAPOINTS AND ; MESSAGEBOX(C_TOOMANYPOINTS_LOC, YESNO_DIALOG + NO_BTN) # IS_YES RETURN .F. ENDCASE * Check for faulty data fields array IF EMPTY(THIS.aDataFields[1]) AND ALEN(THIS.aDataFields)>1 * reset data fields array DIMENSION THIS.aDataFields[1] THIS.aDataFields = "" ENDIF * Check to make sure fields are in data source IF !EMPTY(THIS.cCategoryField) OR !EMPTY(THIS.aDataFields[1]) DIMENSION aFldData[FCOUNT()] FOR i = 1 TO FCOUNT() aFldData[m.i] = FIELD[m.i] ENDFOR IF !EMPTY(THIS.cCategoryField) AND ; (TYPE("THIS.cCategoryField")#"C" OR; ASCAN(aFldData,UPPER(THIS.cCategoryField))=0) =MESSAGEBOX(C_BADCATEGORY_LOC) RETURN .F. ENDIF IF !EMPTY(THIS.aDataFields) FOR i = 1 TO ALEN(THIS.aDataFields) IF TYPE("THIS.aDataFields[m.i]")#"C" OR ASCAN(aFldData,UPPER(THIS.aDataFields[m.i]))=0 =MESSAGEBOX(C_BADDATAFIELD_LOC) RETURN .F. ENDIF ENDFOR ENDIF ENDIF * Check for valid field types DO CASE CASE EMPTY(THIS.cCategoryField) AND EMPTY(THIS.aDataFields) * assume that user wants to use first field as category source THIS.cCategoryField = FIELD[1] CASE EMPTY(THIS.cCategoryField) =ACOPY(THIS.aDataFields,aTmpData) FOR i = 1 TO ALEN(aTmpData) aTmpData[m.i] = UPPER(aTmpData[m.i]) ENDFOR FOR m.i = 1 TO FCOUNT() IF ASCAN(aTmpData,FIELD[m.i])=0 THIS.cCategoryField = FIELD[m.i] EXIT ENDIF ENDFOR ENDCASE * Populate data fields array IF EMPTY(THIS.aDataFields) FOR m.i = 1 TO FCOUNT() IF FIELD[m.i] == UPPER(THIS.cCategoryField) LOOP ENDIF IF !INLIST(TYPE(FIELD[m.i]),'N','F','Y','B') LOOP ENDIF IF !EMPTY(THIS.aDataFields) DIMENSION THIS.aDataFields[ALEN(THIS.aDataFields)+1] ENDIF THIS.aDataFields[ALEN(THIS.aDataFields)] = FIELD[m.i] ENDFOR ENDIF * Check for valid data fields in array FOR m.i = 1 TO ALEN(THIS.aDataFields) IF !(TYPE(THIS.aDataFields[m.i])$ 'NFYB') * Ask if they want to continue IF MESSAGEBOX(C_NOTNUMERIC_LOC, YESNO_DIALOG) # IS_YES RETURN .F. ENDIF ENDIF ENDFOR * Make sure we have right settings THIS.cTitle = ALLTRIM(THIS.cTitle) IF EMPTY(THIS.cTitle) THIS.lAddTitle = .F. ENDIF IF THIS.nGraphVersion = 5 AND THIS.nChartAutoGallery = 16 * Special case here else Graph5 will crash! THIS.nChartAutoGallery = 1 ENDIF RETURN .T. ENDPROC PROCEDURE getoledata *- Assemble Graph Titles and Headers. Put numeric data to be *- graphed into a CF_Text format rectangle. LOCAL cScope PRIVATE i,cOleData,fld,cols,fieldname,nNullCount PRIVATE nfieldvalue,cLinedata m.cOleData = "" m.cLineData = "" THIS.SetCapitals() * Count the numeric fields and fill in the top row of the data rectangle * Can we also use dates? m.cols = 1 FOR m.fld = 1 TO THIS.ntotaldataflds m.fieldname = THIS.aDataFields(m.fld) IF !EMPTY(m.fieldname) AND TYPE(m.fieldname) $ 'NFYB' * _GENXTAB will prepend N_ to a numeric field name "across the top" to form a * valid field name from a number (since xbase fields cannot begin with a number) m.fieldname = IIF(LEFT(m.fieldname,2) = 'N_', SUBSTR(m.fieldname, 3), m.fieldname) m.cOleData = m.cOleData + TAB + m.fieldname m.cols = m.cols + 1 ENDIF ENDFOR m.cOleData = m.cOleData + CRLF IF m.cols = 1 =MESSAGEBOX(C_NODATAFLDS_LOC) RETURN "" ENDIF THIS.nDataCount = 0 * Output one line of data for each record IF THIS.lGraphRecord cScope = "NEXT 1" GOTO THIS.iCurrRec ELSE cScope = "ALL" ENDIF SCAN &cScope * Fill in the leftmost column * Have option to skip empty values !!! m.cLinedata = IIF(EMPTY(THIS.cCategoryField),"",THIS.maptochar(EVAL(THIS.cCategoryField))) nNullCount = 0 * Fill in the data columns FOR m.i = 1 TO THIS.ntotaldataflds && Format numeric fields IF !EMPTY(THIS.aDataFields[m.i]) AND TYPE(THIS.aDataFields[m.i]) $ 'NFYB' fieldname = THIS.aDataFields[m.i] nfieldvalue = EVAL(m.fieldname) DO CASE CASE ISNULL(m.nfieldvalue) cLinedata = m.cLinedata + TAB + "" nNullCount = m.nNullCount + 1 CASE INT(m.nfieldvalue) = m.nfieldvalue && no decimals cLinedata = m.cLinedata + TAB + ALLTRIM(STR(m.nfieldvalue)) CASE TYPE(THIS.aDataFields[m.i])='Y' cLinedata = m.cLinedata + TAB + ALLTRIM(STR(m.nfieldvalue,16,4)) OTHERWISE cLinedata = m.cLinedata + TAB + ALLTRIM(STR(m.nfieldvalue,16,8)) ENDCASE ENDIF ENDFOR * Check for all Mulls IF !THIS.lShowNulls AND THIS.ntotaldataflds = m.nNullCount LOOP ENDIF m.cOleData = m.cOleData + m.cLineData + CRLF THIS.nDataCount = THIS.nDataCount + 1 ENDSCAN IF THIS.lGraphRecord *- reposition record pointer IF BETWEEN(THIS.iCurrRec,1,RECC()) GO THIS.iCurrRec ENDIF ENDIF RETURN m.cOleData ENDPROC PROCEDURE setcapitals * Set capitalization of fields for series IF TYPE("THIS.nCatCapital") # "N" OR !INLIST(THIS.nCatCapital,1,2,3) RETURN ENDIF LOCAL i FOR i = 1 TO ALEN(THIS.aDataFields) DO CASE CASE THIS.nCatCapital = 1 THIS.aDataFields[m.i] = LOWER(THIS.aDataFields[m.i]) CASE THIS.nCatCapital = 2 THIS.aDataFields[m.i] = UPPER(THIS.aDataFields[m.i]) CASE THIS.nCatCapital = 3 THIS.aDataFields[m.i] = PROPER(THIS.aDataFields[m.i]) ENDCASE ENDFOR ENDPROC PROCEDURE maptochar * Converts a variable of any type to a character LPARAMETER m.value LOCAL cDataType m.cDataType = TYPE("m.value") DO CASE CASE ISNULL(m.value) RETURN "Null" CASE INLIST(m.cDataType,'C','M') RETURN m.value CASE INLIST(m.cDataType,'N','F','B','Y') RETURN ALLTRIM(STR(m.value,15)) CASE m.cDataType = 'D' RETURN DTOC(m.value) CASE m.cDataType = 'T' RETURN TTOC(m.value) CASE m.cDataType = 'L' RETURN IIF(m.value, 'YES', 'NO') CASE m.cDataType = 'G' RETURN "Ole" OTHERWISE RETURN "" ENDCASE ENDPROC PROCEDURE addgraphfx LOCAL iSeriesCount, iLegendCount, i WAIT WINDOW NOWAIT C_WAITFORMAT_LOC IF THIS.nAction=2 OR THIS.ngraphVersion<8 *- save to table IF !THIS.GetOleServer() RETURN .F. ENDIF IF TYPE("THIS.oGraphRef.controlsource")#"U" IF THIS.oGraphRef.controlsource#THIS.cGraphField THIS.oGraphRef.controlsource = THIS.cGraphField IF THIS.Haderror RETURN .F. ENDIF ENDIF ENDIF * Add legend THIS.oGraphRef.HasLegend = THIS.lAddLegend * Check for automation error here IF THIS.HadError RETURN .F. ENDIF * Add title THIS.oGraphRef.HasTitle = THIS.lAddTitle IF THIS.lAddTitle THIS.oGraphRef.ChartTitle.caption = THIS.cTitle ENDIF * Set Chart type IF !THIS.lHadPreview &&if user previewed, they may have entered MS Graph and manually changed chart type IF THIS.lUseAutoFormat THIS.oGraphRef.autoformat(THIS.nChartAutoGallery,THIS.nChartAutoFormat) ELSE THIS.oGraphRef.type = THIS.nChartType THIS.oGraphRef.subtype = THIS.nChartSubType ENDIF ENDIF WAIT CLEAR RETURN !THIS.Haderror ELSE *- save to form (or preview) *- Set Chart type IF !THIS.lHadPreview && if user previewed, they may have entered MS Graph and manually changed chart type DO CASE CASE THIS.lUseAutoFormat THIS.oGraphRef.autoformat(THIS.nChartAutoGallery,THIS.nChartAutoFormat) CASE THIS.lUse8Type THIS.oGraphRef.charttype = THIS.nChartType OTHERWISE THIS.oGraphRef.type = THIS.nChartType THIS.oGraphRef.subtype = THIS.nChartSubType ENDCASE ENDIF THIS.oGraphRef.HasLegend = .F. && to force MSGraph recreate legend for graph, to restore count and default objects *- Add title THIS.oGraphRef.HasTitle = THIS.lAddTitle IF THIS.lAddTitle WITH THIS.oGraphRef.ChartTitle .Text = THIS.cTitle ENDWITH ENDIF * Check for automation error here IF THIS.HadError RETURN .F. ENDIF *- we move the orientation around to remove extra series automatically *- added by MS Graph IF THIS.lSeriesByRow THIS.oGraphRef.Application.PlotBy = 2 THIS.ndataseries = THIS.ntotaldataflds ELSE *- THIS.oGraphRef.Application.PlotBy = 1 THIS.ndataseries = THIS.ndatacount ENDIF * Check for automation error here IF THIS.HadError RETURN .F. ENDIF m.iSeriesCount = THIS.oGraphRef.SeriesCollection.Count *- remove unneeded series THIS.SetErrorOff=.T. IF m.iSeriesCount > THIS.ndataseries FOR i = 0 TO m.iSeriesCount - THIS.ndataseries - 1 THIS.oGraphRef.SeriesCollection(m.iSeriesCount - i).Delete IF THIS.HadError THIS.SetErrorOff=.F. RETURN .F. ENDIF NEXT ENDIF THIS.SetErrorOff=.F. *- reset chart orientation to what we really want IF THIS.lSeriesByRow THIS.oGraphRef.Application.PlotBy = 1 THIS.ndataseries = THIS.ndatacount ELSE THIS.oGraphRef.Application.PlotBy = 2 FOR i = THIS.ntotaldataflds + 1 TO 4 *- delete columns -- this will remove unneeded legends, and shift everything to the left THIS.oGraphRef.Application.DataSheet.Range(CHR(65 + THIS.ntotaldataflds)).Delete NEXT IF THIS.lUse8Type AND THIS.lStripExcessLegend THIS.ndataseries = THIS.ntotaldataflds IF THIS.lUseAutoFormat ELSE m.iSeriesCount = THIS.oGraphRef.SeriesCollection.Count *- remove unneeded series IF m.iSeriesCount > THIS.ndataseries FOR i = 0 TO m.iSeriesCount - THIS.ndataseries - 1 IF TYPE("THIS.oGraphRef.SeriesCollection(m.iSeriesCount - i)") == 'O' THIS.oGraphRef.SeriesCollection(m.iSeriesCount - i).Delete ENDIF NEXT ENDIF ENDIF ENDIF ENDIF *- remove datalabels that may be left from a previous graph m.iSeriesCount = THIS.oGraphRef.SeriesCollection.Count FOR i = 1 TO m.iSeriesCount IF TYPE("THIS.oGraphRef.SeriesCollection(i).HasDataLabels") == 'L' THIS.oGraphRef.SeriesCollection(i).HasDataLabels = .F. ENDIF NEXT *- Set Chart type IF !THIS.lHadPreview && if user previewed, they may have entered MS Graph and manually changed chart type DO CASE CASE THIS.lUseAutoFormat THIS.oGraphRef.autoformat(THIS.nChartAutoGallery,THIS.nChartAutoFormat) CASE THIS.lUse8Type THIS.oGraphRef.charttype = THIS.nChartType OTHERWISE THIS.oGraphRef.type = THIS.nChartType THIS.oGraphRef.subtype = THIS.nChartSubType ENDCASE ENDIF *- Add legend THIS.oGraphRef.HasLegend = THIS.lAddLegend IF THIS.lAddLegend WITH THIS.oGraphRef.Legend IF THIS.lUse8Type m.iLegendCount = .LegendEntries.Count IF !THIS.lDontStripLegend IF m.iLegendCount > THIS.ndataseries FOR i = 0 TO m.iLegendCount - THIS.ndataseries - 1 IF TYPE(".LegendEntries(m.iLegendCount - i)") == 'O' .LegendEntries(m.iLegendCount - i).Delete ENDIF NEXT ENDIF ENDIF ENDIF ENDWITH ENDIF WAIT CLEAR RETURN !THIS.Haderror ENDIF && nAction = 2 (save to table) ENDPROC PROCEDURE getoleserver LOCAL iHeight, iWidth, lSetPreviewProps LOCAL lCreateForm, lAddGraphObject, cAppName, cAppVersion lCreateForm = .T. lAddGraphObject = .T. *- see if user passed in valid objects IF TYPE("THIS.GraphPreview") == 'O' AND !ISNULL(THIS.GraphPreview) IF LOWER(ALLTRIM(THIS.GraphPreview.BaseClass)) == "form" lCreateForm = .F. ENDIF ENDIF THIS.HadError = .F. IF TYPE("THIS.oGraphRef") == 'O' AND !ISNULL(THIS.oGraphRef) cAppName = THIS.oGraphRef.application.name IF !THIS.HadError IF m.cAppName = MSGRAPH_APPNAME cAppVersion = VAL(THIS.oGraphRef.application.version) IF !THIS.HadError IF m.cAppVersion >= MSGRAPH_VERSION lAddGraphObject = .F. ENDIF ENDIF ENDIF ENDIF ENDIF THIS.HadError = .F. *- Need to activate server DO CASE CASE THIS.lAutoGraph AND ATC(JUSTEXT(THIS.cOutFile),"DBF")#0 THIS.graphpreview = CREATE(THIS.cGraphPrevClass) THIS.oGraphRef = THIS.graphpreview.oleboundcontrol1 m.lSetPreviewProps = .F. CASE THIS.lAutoGraph IF m.lCreateForm THIS.graphpreview = CREATEOBJ("form") THIS.graphpreview.DefOleLCID = 0 ENDIF IF m.lAddGraphObject THIS.graphpreview.AddObject("oChart","oleControl",MSGRAPH_8_CLASS) THIS.graphpreview.oChart.Visible = .T. THIS.oGraphRef = THIS.graphpreview.oChart.Object iheight = 200 iwidth = 300 m.lSetPreviewProps = .T. ENDIF CASE (THIS.nAction == 2 OR THIS.ngraphVersion < 8) AND ; ((TYPE('THIS.graphpreview')#'O' AND; TYPE('THIS.oGraphRef')#'O') OR; ISNULL(THIS.GraphPreview)) THIS.graphpreview = CREATE(THIS.cGraphPrevClass) THIS.oGraphRef = THIS.graphpreview.oleboundcontrol1 m.lSetPreviewProps = .F. CASE (TYPE('THIS.graphpreview')#'O' AND; TYPE('THIS.oGraphRef')#'O') OR; ISNULL(THIS.GraphPreview) IF m.lCreateForm THIS.graphpreview = CREATE("form") ENDIF IF m.lAddGraphObject THIS.graphpreview.AddObject("oChart","oleControl",MSGRAPH_8_CLASS) THIS.oGraphRef = THIS.graphpreview.oChart.Object iheight = 250 iwidth = 450 m.lSetPreviewProps = .T. ENDIF IF m.lCreateForm WITH THIS.graphPreview .Height = 315 .Width = 450 .Caption = C_PRVWCAPTION_LOC .AlwaysOnTop = .T. .AutoCenter = .T. .Closable = .F. .WindowType = 1 .NewObject("cmdReturn","cmdReturn",THIS.classlibrary) .cmdReturn.Visible = .T. .cmdReturn.Left = 156 .cmdReturn.Top = 265 ENDWITH ENDIF ENDCASE IF TYPE('THIS.oGraphRef') # 'O' OR THIS.Haderror RETURN .F. ENDIF IF m.lSetPreviewProps AND TYPE("THIS.graphpreview.oChart") == 'O' AND !ISNULL(THIS.graphpreview.oChart) WITH THIS.graphpreview.oChart .height = m.iHeight .width = m.iWidth .autosize = .t. .stretch = 1 .visible = .t. ENDWITH ENDIF ENDPROC PROCEDURE Init THIS.nSaveLocaleId = VAL(SYS(3004)) IF !DODEFAULT() RETURN .F. ENDIF RETURN THIS.MSGraphCheck() ENDPROC PROCEDURE makeoutput LOCAL cTmpFld,cQPRFile,cOldSafe,cGraphField THIS.HadError = .F. *- Quick check for source table. DO CASE CASE EMPTY(THIS.cAlias) AND EMPTY(ALIAS()) =MESSAGEBOX(C_NOSOURCE_LOC) RETURN .F. CASE EMPTY(THIS.cAlias) THIS.cAlias = ALIAS() OTHERWISE SELECT (THIS.cAlias) ENDCASE IF EMPTY(THIS.cOutFile) AND THIS.nAction # 0 THIS.GetSaveFile(ALIAS()) IF EMPTY(THIS.cOutFile) RETURN ENDIF IF THIS.lAutoGraph AND ATC(JUSTEXT(THIS.cOutFile),"DBF")#0 THIS.nAction = 2 ENDIF ENDIF IF THIS.lGraphRecord IF BETWEEN(RECNO(),1,RECC()) THIS.iCurrRec = RECNO() ELSE *- EOF or BOF RETURN ENDIF ENDIF IF THIS.nAction = 3 && Save and open query IF !THIS.CheckData() RETURN .F. ENDIF THIS.MakeQPR() m.cQPRFile = "'" + THIS.cOutFile + "'" _SHELL = [MODIFY QUERY &cQPRFile NOWAIT] RETURN ENDIF *** Start Using OLE Automation *** * We need to make sure that we are using English * version so that server understands commands. =SYS(3006,1033) IF THIS.nAction # THIS.nLastAction AND !THIS.lKeepForm THIS.oGraphRef = "" THIS.graphpreview = "" THIS.nLastAction = THIS.nAction THIS.lAddedData = .F. ENDIF IF !THIS.AddGraphData() RETURN .F. ENDIF IF !THIS.AddGraphFx() RETURN .F. ENDIF DO CASE CASE THIS.nAction = 0 && Preview graph IF TYPE("THIS.graphpreview") == "O" AND THIS.lShowWhenDone THIS.graphpreview.show ENDIF CASE THIS.nAction = 1 && Save graph to a form m.cOldSafe = SET("SAFETY") SET SAFETY OFF WITH THIS.graphpreview IF TYPE("THIS.graphpreview.cmdReturn") == 'O' AND !ISNULL(.cmdReturn) .RemoveObject("cmdReturn") ENDIF .WindowType = 0 .AlwaysOnTop = .F. .Closable = .T. .Caption = IIF(EMPTY(CURSORGETPROP("DATABASE", THIS.cAlias)), THIS.cAlias, CURSORGETPROP("SourceName", THIS.cAlias)) .SaveAs(THIS.cOutFile) ENDWITH SET SAFETY &cOldSafe IF THIS.Haderror THIS.ALERT(C_HADERROR_LOC) RETURN .F. ENDIF IF INLIST(PROGRAM(1),"GRSTART","WIZARD") OR THIS.lAutoGraph _SHELL = [MODIFY FORM "] + THIS.cOutFile + ["] ENDIF CASE THIS.nAction = 2 && Save graph to table THIS.oGraphRef = "" THIS.graphpreview = "" * Save to new table m.cOldSafe = SET("SAFETY") SET SAFETY OFF m.cGraphField = THIS.cGraphField THIS.Haderror = .F. * Overwrite table / Append existing table THIS.SetErrorOff = .T. IF !FILE(THIS.cOutFile) OR THIS.lReplaceDBF OR EMPTY(THIS.cOutGenField) CREATE TABLE (THIS.cOutFile) FREE ((THIS.cDefNewField) g) INSERT INTO (DBF()) VALUE(vfpgtemp.&cGraphField.) ELSE IF EMPTY(THIS.cOpenAlias) SELECT 0 USE (THIS.cOutFile) AGAIN SHARED ELSE SELECT (THIS.cOpenAlias) ENDIF INSERT INTO (DBF()) ((THIS.cOutGenField)) VALUE(vfpgtemp.&cGraphField.) THIS.cDefNewField = THIS.cOutGenField ENDIF THIS.SetErrorOff = .F. SET SAFETY &cOldSafe IF THIS.Haderror THIS.ALERT(C_HADERROR_LOC) RETURN .F. ENDIF m.cTmpFld = ALIAS() + "." + THIS.cDefNewField * Check to see where Graph Wizard was called from * Avoid using if it was called programmatically IF INLIST(PROGRAM(1),"GRSTART","WIZARD") OR THIS.lAutoGraph DO CASE CASE TYPE("oEngine") == 'O' oEngine.AddAliasToPreservedList(ALIAS()) CASE TYPE("oWizard") == 'O' oWizard.AddAliasToPreservedList(ALIAS()) ENDCASE _SHELL = [MODIFY GENERAL &cTmpFld NOWAIT] ELSE ENDIF ENDCASE ENDPROC PROCEDURE Destroy THIS.oGraphRef = "" THIS.graphpreview = "" IF USED('vfpgtemp') USE IN vfpgtemp ENDIF DODEFAULT() ENDPROC PROCEDURE Error LPARAMETERS nError, cMethod, nLine * Check for OLE error, otherwise pass it on LOCAL nTotErrors,aErrs IF THIS.SetErrorOff THIS.HadError = .T. RETURN ENDIF DIMENSION aErrs[1] m.nTotErrors=AERROR(aErrs) IF m.nTotErrors>0 AND BETWEEN(aErrs[1],1420,1460) THIS.ALERT(C_OLEERROR_LOC + " (Error: " + ALLTRIM(STR(aErrs[1])) + ")") THIS.HadError = .T. RETURN ENDIF * Make sure we reset the Localization ID =SYS(3006,THIS.nSaveLocaleId) Automation::ERROR(m.nError,m.cMethod,m.nLine) ENDPROC PROCEDURE checkdata LOCAL lRetVal,cOldExact *- Check for valid data m.cOldExact = SET("EXACT") SET EXACT ON && for ASCANs m.lRetVal = THIS.ValidDataTable() SET EXACT &cOldExact IF !m.lRetVal THIS.lAddedData = .F. RETURN .F. ENDIF ENDPROC